"""
-- coding: utf-8 --
@Time : 2024/1/8
@Author : 张书译
@Describe: APP UI自动化方法封装
"""
import os
import subprocess

from Comm.unit.Adb import adb
from appium import webdriver
from Logger import logger
import multiprocessing
import config


def Text(driver, TEXT, SEND=None):
    """
    :param SEND: 输入文本
    :param TEXT: 通过TEXT获取元素进行操作
    :return: selectTag
    """
    try:
        selectTag = driver.find_element(TEXT)
        if SEND is None:
            selectTag.click()
            logger.info(f"获取{TEXT}元素，并且点击")
        else:
            selectTag.send_keys(SEND)
            logger.info(f"获取{TEXT}元素，并且输入{SEND}")
        return selectTag
    except EOFError as e:
        logger.info(f"{e}, 未获取到TEXT：{TEXT}")


class AppniumMethod:

    def __init__(self, port=4723):
        self.server_path = config.appium_server_path
        self.port = port
        self.appium_log_path = os.path.join(config.LOG_DIR, "appium_server_{0}.log".format(port))
        self.server = 'http://localhost:4723/wd/hub'
        self.devices_list = adb.getVersion()
        # 构建线程组
        self.desired_process = []

    def start_appium_server(self):
        """启动appium server服务"""
        cmd = f'start /b {self.server_path} -a 127.0.0.1 -p {self.port} --log {self.appium_log_path} --local-timezone'
        subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()

    @classmethod
    def stop_appium(cls, pc, post_num=4723):
        """关闭appium服务"""
        if pc.upper() == 'WIN':
            p = os.popen(f'netstat  -aon|findstr {post_num}')
            p0 = p.read().strip()
            if p0 != '' and 'LISTENING' in p0:
                p1 = int(p0.split('LISTENING')[1].strip()[0:4])  # 获取进程号
                os.popen(f'taskkill /F /PID {p1}')  # 结束进程
                logger.info('appium server已结束')
        elif pc.upper() == 'MAC':
            p = os.popen(f'lsof -i tcp:{post_num}')
            p0 = p.read()
            if p0.strip() != '':
                p1 = int(p0.split('\n')[1].split()[1])  # 获取进程号
                os.popen(f'kill {p1}')  # 结束进程
                logger.info('appium server已结束')

    def Desired_caps(self, cap):
        logger.info("appium port:%s start run %s at" % (self.server, cap))
        AppDriver = webdriver.Remote(self.server, cap)
        return AppDriver

    def set_desired(self):
        # 加载desired进程
        for i in range(len(self.devices_list)):
            port = 4723 + 2 * i
            desired = multiprocessing.Process(target=self.Desired_caps, args=(self.devices_list[i], port))
            self.desired_process.append(desired)  # 将设备添加到里面，ip和端口

    def run_desired_pro(self):
        for desired in self.desired_process:
            desired.start()

        for desired in self.desired_process:
            desired.join()

    def method(self, met, driver, element, send=None):
        if met == 'id':
            self.Id(driver, element, send)
        elif met == 'xpath':
            self.xpath(driver, element, send)
        elif met == 'class_name':
            self.CName(driver, element, send)
        elif met == 'css_selector':
            self.CssSelector(driver, element, send)
        elif met == 'partial_link_text':
            self.PLText(driver, element, send)
        elif met == 'android_uiautomator':
            self.au(driver, element, send)

    @staticmethod
    def Id(driver, ID, SEND=None):
        """
        :param driver: 驱动
        :param SEND: 输入文本
        :param ID: 通过ID获取元素进行操作
        :return:
        """
        try:
            selectTag = driver.find_element_by_id(ID)
            if SEND is None:
                selectTag.click()
                logger.info(f"获取{ID}元素，并且点击")
            else:
                selectTag.send_keys(SEND)
                logger.info(f"获取{ID}元素，并且输入{SEND}")
            return selectTag
        except EOFError as e:
            logger.info(f"{e}, 未获取到id：{ID}")

    @staticmethod
    def CssSelector(driver, CssSelector, SEND=None):
        """
        :param driver: 驱动
        :param SEND: 输入文本
        :param CssSelector: 通过CssSelector获取元素进行操作
        :return:selectTag
        """
        try:
            selectTag = driver.find_element_by_accessibility_id(CssSelector)
            if SEND is None:
                selectTag.click()
                logger.info(f"获取{CssSelector}元素，并且点击")
            else:
                selectTag.send_keys(SEND)
                logger.info(f"获取{CssSelector}元素，并且输入{SEND}")
            return selectTag
        except EOFError as e:
            logger.info(f"{e}, 未获取到name：{CssSelector}")

    @staticmethod
    def PLText(driver, PLText, SEND=None):
        """
        :param driver: 驱动
        :param SEND: 输入文本
        :param PLText: 通过PLText获取元素进行操作
        :return:selectTag
        """
        try:
            selectTag = driver.find_element_by_partial_link_text(PLText)
            if SEND is None:
                selectTag.click()
                logger.info(f"获取{PLText}元素，并且点击")
            else:
                selectTag.send_keys(SEND)
                logger.info(f"获取{PLText}元素，并且输入{SEND}")
            return selectTag
        except EOFError as e:
            logger.info(f"{e}, 未获取到name：{PLText}")

    @staticmethod
    def CName(driver, CName, SEND=None):
        """
        :param driver: 驱动
        :param SEND: 输入文本
        :param CName: 通过CLASSNAME获取元素进行操作
        :return:
        """
        try:
            selectTag = driver.find_element_by_class_name(CName)
            if SEND is None:
                selectTag.click()
                logger.info(f"获取{CName}元素，并且点击")
            else:
                selectTag.send_keys(SEND)
                logger.info(f"获取{CName}元素，并且输入{SEND}")
            return selectTag
        except EOFError as e:
            logger.info(f"{e}, 未获取到CLASS_NAME：{CName}")

    @staticmethod
    def TName(driver, TagName, SEND=None):
        """
        :param driver: 驱动
        :param SEND: 输入文本
        :param TagName: 通过TagName获取元素进行操作
        :return: selectTag
        """
        try:
            selectTag = driver.find_element_by_tag_name(TagName)
            if SEND is None:
                selectTag.click()
                logger.info(f"获取{TagName}元素，并且点击")
            else:
                selectTag.send_keys(SEND)
                logger.info(f"获取{TagName}元素，并且输入{SEND}")
            return selectTag
        except EOFError as e:
            logger.info(f"{e}, 未获取到TAG_NAME：{TagName}")

    @staticmethod
    def xpath(driver, XPATH, SEND=None):
        """
        :param driver: 驱动
        :param SEND: 输入文本
        :param XPATH: 通过XPATH获取元素进行操作
        :return: selectTag
        """
        try:
            selectTag = driver.find_element_by_xpath(XPATH)
            if SEND is None:
                selectTag.click()
                logger.info(f"获取{XPATH}元素，并且点击")
            else:
                selectTag.send_keys(SEND)
                logger.info(f"获取{XPATH}元素，并且输入{SEND}")
            return selectTag
        except EOFError as e:
            logger.info(f"{e}, 未获取到XPATH：{XPATH}")

    @staticmethod
    def au(driver, au, SEND=None):
        """
        :param driver: 驱动
        :param SEND: 输入文本
        :param au: 原生定位
        :return: selectTag
        """
        try:
            selectTag = driver.find_element_by_android_uiautomator(au)
            if SEND is None:
                selectTag.click()
                logger.info(f"获取{au}元素，并且点击")
            else:
                selectTag.send_keys(SEND)
                logger.info(f"获取{au}元素，并且输入{SEND}")
            return selectTag
        except EOFError as e:
            logger.info(f"{e}, 未获取到XPATH：{au}")
